#ifndef __CHUNKRENDERER__
#define __CHUNKRENDERER__

#include "..\Schematics\Schematic.h"
#include "..\Schematics\Block.h"
#include "RendererBase.h"
#include "IBlockRenderer.h"
#include "IReportProgress.h"

/// <summary>
/// Class to render an entire chunk of blocks from a schematic.
/// </summary>
class ChunkRenderer : IProvidePosition
{
	Point3i _curPos;
	Schematic *_schematic;

public:
	IReportProgress *ProgressReporter;
	const Point3i &GetPosition() { return _curPos; }

	/// <summary>
	/// Constructor.
	/// </summary>
	/// <param name="schematic">The schematic to render chunks from.</param>
	ChunkRenderer(Schematic *schematic) :
		_schematic(schematic),
		ProgressReporter(nullptr)
	{
	}

	void RenderChunk(PrimitiveRendererBase *renderData, const Point3i &position, const Point3i &length)
	{
		renderData->PositionProvider = this;

		if (ProgressReporter != nullptr)
			ProgressReporter->SetProgressGoal(length.Y * length.Z * length.X, "Rendering");

		for (int y = 0; y < length.Y; ++y)
			for (int z = 0; z < length.Z; ++z)
				for (int x = 0; x < length.X; ++x)
				{
					if (ProgressReporter != nullptr)
						if (ProgressReporter->IncrementProgress())
							return;

					_curPos = Point3i(position.X + x, position.Y + y, position.Z + z);
					auto &block = _schematic->GetBlock(_curPos.X, _curPos.Y, _curPos.Z);

					if (block == Block::Empty)
						continue;

					renderData->PushState();
					renderData->Translate(x * 16, (length.Y - y) * 16, z * 16);
					renderData->GetRenderer()->ExecuteRenderer(renderData, _schematic, block, _curPos);
					renderData->PopState();
				}
	}
};
#endif